	import Util.DrawGraph;
	import Util.Tools;
	
	import algorithm.Dijkstra;
	import algorithm.Huffman;
	import algorithm.Kruskal;
	import algorithm.Prim;
	
	import data.Helper;
	
	import datastructure.Edge;
	import datastructure.EdgeAbstract;
	import datastructure.Graph;
	import datastructure.HTNode;
	import datastructure.Vertex;
	
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import mx.controls.Alert;
	import mx.controls.Label;
	import mx.core.UIComponent;
	import mx.events.ValidationResultEvent;
	import mx.utils.StringUtil;
	
	import org.osmf.utils.Version;
	
	import spark.components.Label;
	import spark.components.TextArea;
	
	import view.NodeCircle;
	
	
	
	private var g:Graph;
	private var graphContainer:Sprite;
	
	private var index:int;
	private var timer:Timer;
	private var isExecPrim:Boolean = false;

	private function iniApp():void
	{
		initGraph();
		initPrim();
	}

	private function initPrim():void
	{
		this.oriGraPanel.removeAllElements();
		var comp:UIComponent = new UIComponent();
		comp.addChild(this.graphContainer);
		this.oriGraPanel.addElement(comp);
		//this.oriKruGraPanel.addElement(comp);
	}
	
	/**
	 * 初始化图 
	 * 
	 */
	private function initGraph():void
	{
		this.g = new Graph(Helper.vertexArray.length);
		for(var i:int = 0;i < Helper.edgeArray.length;i++)
		{
			g.setEdge(Helper.edgeArray[i].startVer.index,Helper.edgeArray[i].endVer.index,Helper.edgeArray[i].weight);
			g.setEdge(Helper.edgeArray[i].endVer.index,Helper.edgeArray[i].startVer.index,Helper.edgeArray[i].weight);
		}
		
		Tools.setVertexPosition(Helper.vertexArray,Helper.positions);
		
		graphContainer = new Sprite();
		graphContainer.x = 0;
		graphContainer.y = 0;
		DrawGraph.drawVertex(Helper.vertexArray,this.graphContainer);
		DrawGraph.drawLines(Helper.edgeArray,this.graphContainer);
	}

	
	/**
	 * 执行prim算法 
	 * 
	 */
	private function execPrim():void
	{
		if(this.isExecPrim)
		{
			Alert.show("请点击刷新按钮刷新后再重新执行！","温馨提示");
		}
		else
		{
			
			var startV:Vertex = this.getStartVertex(this.userInput.text);
			if(startV == null)
			{
				Alert.show("不存在该顶点！","温馨提示");
			}
			else
			{
				this.isExecPrim = true;
				var prim:Prim = new Prim(this.g,startV,Helper.vertexArray);
				prim.run();
				this.mstGraPanel.visible = true;
				transformer.play();
				
				var msTreeContainer:Sprite = new Sprite();
				msTreeContainer.x = 0;
				msTreeContainer.y = 0;
				DrawGraph.drawVertex(prim.getVersMST(),msTreeContainer);
				dynaAddLines(prim.geTMST(),msTreeContainer);
				var mstComp:UIComponent = new UIComponent();
				mstComp.addChild(msTreeContainer);
				this.mstGraPanel.addElement(mstComp);
			}
		}
		
	}


	private function refreshPrim():void
	{
		this.mstGraPanel.removeAllElements();
		this.mstGraPanel.visible = false;
		this.isExecPrim = false;
		this.refreshPrimBtn.visible = false;
		this.timer = null;
		
		this.setVertexToOriState();
		
		//navigateToURL(new URLRequest("javascript:location.reload();"),"_self")
		
	}

	private function setVertexToOriState():void
	{
		for(var i:int = 0; i < Helper.vertexArray.length;i++)
		{
			Helper.vertexArray[i].isStart = false;
			Helper.vertexArray[i].closestVer = null;
			Helper.vertexArray[i].closestDist = int.MAX_VALUE;
		}
	}


	/**
	 * 动态演示添加边的次序 
	 * @param edgeArray
	 * @param msTreeContainer
	 * 
	 */	
	private function dynaAddLines(edgeArray:Array,msTreeContainer:Sprite):void
	{
		this.index  = 0;
		this.timer = new Timer(1000, edgeArray.length);
		timer.addEventListener(TimerEvent.TIMER,function(evt:TimerEvent){addLines(evt,msTreeContainer,edgeArray);});
		timer.start();
	}
	
	private function addLines(event:TimerEvent,msTreeContainer:Sprite,edgeArray:Array):void 
	{
		DrawGraph.drawLines( [edgeArray[this.index]],msTreeContainer);
		trace(edgeArray[this.index].weight);
		this.index ++;
		if(this.index == edgeArray.length)
		{
			this.timer.stop();
			Alert.show("执行完毕！","温馨提示");
			this.refreshPrimBtn.visible = true;
			this.index = 0;
		}
		
	}

	/**
	 * 根据用户输入，获取初始顶点 
	 * @param userInput
	 * @return 
	 * 
	 */	
	private function getStartVertex(userInput:String):Vertex
	{
		for(var i:int = 0; i < Helper.vertexArray.length;i++)
		{
			if(Helper.vertexArray[i].name == StringUtil.trim(userInput))
			{
				return Helper.vertexArray[i];
			}
		}
		return null;
	}

	/*~~~~~~~~~~~~~~~Kruskal~~~~~~~~~~~~~~~~~*/
	[Bindable]
	private var isExecKruskal:Boolean = false;
	
	private function initKruskal():void
	{
		this.oriKruGraPanel.removeAllElements();
		var comp:UIComponent = new UIComponent();
		comp.addChild(this.graphContainer);
		this.oriKruGraPanel.addElement(comp);
	//	this.initKruskalBtn.enabled = false;
	}

	private function getOriGraphEdges(mstKru:Array):Array
	{
		var oriGraphEdges:Array = new Array();
		for(var i:int = 0;i < mstKru.length; i++)
		{
			for(var j:int = 0;j < Helper.edgeArray.length;j++)
			{
				if(mstKru[i].start == Helper.edgeArray[j].startVer.index && mstKru[i].end == Helper.edgeArray[j].endVer.index)
				{
					oriGraphEdges.push(Helper.edgeArray[j]);
				}
			}
		}
		
		return oriGraphEdges;
	}


	private function execKruskal():void
	{
		
		
		//var edges:Array = getOriGraphEdges(kru.getMstKru());
		/*for each (var e:Edge in edges)
		{
			trace( e.startVer.name + " " + e.endVer.name + " " + e.weight);
		}*/
		
		
		if(this.isExecKruskal)
		{
			Alert.show("请点击刷新按钮刷新后再重新执行！","温馨提示");
		}
		else
		{
			this.isExecKruskal = true;
			var kru:Kruskal = new Kruskal(this.g);
			kru.runKruskal();
			this.mstKruGraPanel.visible = true;
			transformer.play();
			
			var kruMSTreeContainer:Sprite = new Sprite();
			kruMSTreeContainer.x = 0;
			kruMSTreeContainer.y = 0;
			DrawGraph.drawVertex(Helper.vertexArray,kruMSTreeContainer);
			dynaAddLines(getOriGraphEdges(kru.getMstKru()),kruMSTreeContainer);
			var mstKruComp:UIComponent = new UIComponent();
			mstKruComp.addChild(kruMSTreeContainer);
			this.mstKruGraPanel.addElement(mstKruComp);
		}
		
		
	}

	private function refreshKruskal():void
	{
		this.mstKruGraPanel.removeAllElements();
		this.mstKruGraPanel.visible = false;
		this.isExecKruskal = false;
		this.timer = null;
	}


	/*~~~~~~~~~~~~~~~~~~~~~Dijkstra~~~~~~~~~~~~~~~~~~~~~~~~*/

	[Bindable]
	private var isExecDijkstra:Boolean = false;
	
	private function initDijkstra():void
	{
		this.oriDijGraPanel.removeAllElements();
		var comp:UIComponent = new UIComponent();
		comp.addChild(this.graphContainer);
		this.oriDijGraPanel.addElement(comp);
		//this.initDijkstraBtn.enabled = false;
	}
	
	private function execDijkstra():void
	{
		if(this.isExecDijkstra)
		{
			Alert.show("请点击刷新按钮刷新后再重新执行！","温馨提示");
		}
		else
		{
			
			var startV:Vertex = this.getStartVertex(this.userInput_Dijkstra.text);
			if(startV == null)
			{
				Alert.show("不存在该顶点！","温馨提示");
			}
			else
			{
				this.isExecDijkstra = true;
				var dijkstra:Dijkstra = new Dijkstra(this.g,startV,Helper.vertexArray);
				dijkstra.runDijkstra();
				
				this.pathsDijGraPanel.visible = true;
				this.textDijkstraPanel.visible = true;
				
				var pathseContainer:Sprite = new Sprite();
				pathseContainer.x = 0;
				pathseContainer.y = 0;
				DrawGraph.drawVertex(dijkstra.getVT(),pathseContainer);
				dynaAddLines(dijkstra.getPaths(),pathseContainer);
				var pathsComp:UIComponent = new UIComponent();
				pathsComp.addChild(pathseContainer);
				this.pathsDijGraPanel.addElement(pathsComp);
				
				var ta:spark.components.Label= new spark.components.Label();
				ta.text = dijkstra.getPathsShow();
				ta.x = 50;
				ta.y = 50;
				this.textDijkstraPanel.addElement(ta);
				//trace();
			}
		}
		
		/*var va:Array = dijkstra.getVT();
		for each (var v:Vertex in va)
		{
			if(v.closestVer != null)
			{
				trace(v.name + " " + v.closestVer.name + " " + v.closestDist);
			}
			
		}*/
		
	}

	private function refreshDijkstra():void
	{
		this.pathsDijGraPanel.removeAllElements();
		this.pathsDijGraPanel.visible = false;
		this.textDijkstraPanel.removeAllElements();
		this.textDijkstraPanel.visible = false;
		this.isExecDijkstra = false;
		this.timer = null;
		
		this.setVertexToOriState();
	}


	/*~~~~~~~~~~~~~~~~Huffman~~~~~~~~~~~~~~~~~~~~~~~*/
	[Bindable]
	private var isExecHuffman:Boolean = false;
	private var oriHuffNodes:Array = null;	//动态添加的哈夫曼节点数组
	
	/**
	 * 添加哈夫曼节点 
	 * 
	 */
	private function addHuffmanNode():void
	{
		if(this.oriHuffNodes == null)
		{
			this.oriHuffNodes = new Array();
		}
		
		var proba:Number = Number(Number(StringUtil.trim(this.probabilityInput_Huffman.text)).toFixed(3));
		var nam:String = StringUtil.trim(this.charNameInput_Huffman.text) + ":" + proba;
		var obj:Object = new Object();
		obj.name = nam;
		obj.probability = proba;
		
		if(this.isCharExits(obj.name))
		{
			Alert.show("该字符已经存在，请换个名字再添加！","温馨提示");
		}
		else
		{
			this.oriHuffNodes.push(obj);
			var nodeVisul:NodeCircle = new NodeCircle(obj.name);
			nodeVisul.x = this.oriHuffNodes.length * 40;
			var nodeComp:UIComponent = new UIComponent();
			nodeComp.addChild(nodeVisul);
			this.oriNodesContainer_Huffman.addElement(nodeComp);
		}
		
	}

	/**
	 * 验证添加节点的属性值是否符合要求，若符合要求则添加节点 
	 * 
	 */	
	private function valiAllInput_Haffuman():void
	{
		var vResultCharName:ValidationResultEvent = this.charNameInput_HuffmanValidator.validate();
		var vResultProbability:ValidationResultEvent =  this.probabilityInput_HuffmanValidator.validate();
		if(vResultCharName.type == ValidationResultEvent.VALID &&
			vResultProbability.type == ValidationResultEvent.VALID)
		{
			this.addHuffmanNode();
		}
		
	}

	/**
	 * 判断所要添加的字符是否已经存在 
	 * @param charName
	 * @return 
	 * 
	 */	
	private function isCharExits(charName:String):Boolean
	{
		
		for(var i:int = 0;i < this.oriHuffNodes.length; i++)
		{
			if(this.oriHuffNodes[i].name == charName)
			{
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 执行Huffman算法 
	 * 
	 */	
	private function execHuffman():void
	{
		if(this.isExecHuffman)
		{
			Alert.show("请点击刷新按钮刷新后再重新执行！","温馨提示");
		}
		else
		{
			if(this.oriHuffNodes == null)
			{
				Alert.show("还未添加节点，请添加节点后再执行！","温馨提示");
			}
			else
			{
				this.isExecHuffman = true;
				var huffman:Huffman = new Huffman(this.oriHuffNodes);
				huffman.runHuffman();
				//var root:HTNode = huffman.getHuffmanTree();
				huffman.inorder(huffman.getHuffmanTree());
				
				
				var treeContainer:Sprite = new Sprite();
				treeContainer.x = 300;
				treeContainer.y = 32;
				DrawGraph.drawNodes(huffman.getHuffmanTree(),treeContainer);
				DrawGraph.drawLinesTree(huffman.getHuffmanTree(),treeContainer);
				
				var compTree:UIComponent = new UIComponent();
				compTree.addChild(treeContainer);
				this.huffmanTreePanel.addElement(compTree);
				
				
				var huffmanNodes:Array = huffman.getHuffmanNodes();
				var coding:String = "";
				for(var i:int = 0; i < huffmanNodes.length; i++)
				{
					coding += huffmanNodes[i].name + "  编码为：" + huffman.getNodeCode(huffmanNodes[i]) + '\n';
				}
				//Alert.show(coding);
				
				var codingOuput:spark.components.Label= new spark.components.Label();
				codingOuput.text = coding;
				codingOuput.x = 50;
				codingOuput.y = 50;
				this.codingOutputPanel.addElement(codingOuput);
			}
			
		}
	}

	private function refreshHuffman():void
	{
		this.charNameInput_Huffman.text = "";
		this.probabilityInput_Huffman.text = "";
		this.oriNodesContainer_Huffman.removeAllElements();
		this.huffmanTreePanel.removeAllElements();
		this.codingOutputPanel.removeAllElements();
		this.isExecHuffman = false;
		this.oriHuffNodes = null;
	}


	









